package com.tbl.modules.wms2.common;

import cn.hutool.core.date.DateUtil;
import cn.hutool.system.SystemUtil;
import com.tbl.modules.platform.entity.system.User;
import com.tbl.modules.wms2.common.support.SysLogEntity;
import com.tbl.modules.wms2.service.common.SpLogService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


/**
 * 系统日志，切面处理类
 *
 * @author Dash
 */

@Aspect
@Component
public class SysLogAspect {

    private static final Logger log = LoggerFactory.getLogger(SysLogAspect.class);

    @Resource
    private SpLogService spLogService;


    /**
     * 使用注解的形式
     * 当然，也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method
     * 切点表达式:   execution(...)
     */
    @Pointcut("execution(* com.tbl.modules.wms2.controller..*.*(..))")
    public void pointCut() {

    }


    /**
     * 前置通知
     *
     * @param joinPoint
     */

    @Before("pointCut()")
    public void beforeMethod(JoinPoint joinPoint) {
        log.info("调用了前置通知");
    }


    /**
     * 后置通知
     *
     * @param joinPoint
     */

    @After("pointCut()")
    public void afterMethod(JoinPoint joinPoint) {
        log.info("调用了后置通知");
    }


    /**
     * 返回通知 result为返回内容
     *
     * @param joinPoint
     * @param result
     */

    @AfterReturning(value = "pointCut()", returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, Object result) {
        saveSysLog(joinPoint, null);
    }


    /**
     * 拦截异常通知
     *
     * @param joinPoint 切点
     * @param e         异常
     */

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void afterReturningMethod(JoinPoint joinPoint, Exception exception) {
        saveSysLog(joinPoint, exception);
    }


    /**
     * 环绕通知
     *
     * @param point
     * @return
     * @throws Throwable
     */

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
//		saveSysLog(point, time);
        return result;
    }


    /**
     * 保存日志
     *
     * @param joinPoint
     * @param exception
     */

    private void saveSysLog(final JoinPoint joinPoint, final Exception exception) {
        System.out.println(joinPoint);

        try {
            // 获得注解
//            SysLog sysLog = getAnnotation(joinPoint);
//            if (sysLog == null) {
//                return;
//            }

            SysLogEntity sysLogEntity = new SysLogEntity();
//            sysLogEntity.setUserid(String.valueOf(getSessionUser().getUserId()));
//            sysLogEntity.setUsername(getSessionUser().getUsername());
            sysLogEntity.setIp(SystemUtil.getHostInfo().getAddress());
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            sysLogEntity.setClassName(className);
            sysLogEntity.setClassMethod(methodName);

            sysLogEntity.setCreateTime(DateUtil.date());
//            // 设置注解上传参数
//            getAnnotationParam(sysLog, sysLogEntity);
            spLogService.createLog(sysLogEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


/**
 * 设置注解上传参数
 *
 * @param sysLog
 * @param sysLogEntity
 * <p>
 * 是否存在注解，如果存在就获取
 * @param joinPoint+
 * @return
 * @throws Exception
 * <p>
 */

//    public void getAnnotationParam(SysLog sysLog, SysLogEntity sysLogEntity) {
//        // 操作说明
//        sysLogEntity.setRemarks(sysLog.value());
//    }


/**
 * 是否存在注解，如果存在就获取
 *
 * @param joinPoint
 * @return
 * @throws Exception
 */

//    private SysLog getAnnotation(JoinPoint joinPoint) throws Exception {
//        Signature signature = joinPoint.getSignature();
//        MethodSignature methodSignature = (MethodSignature) signature;
//        Method method = methodSignature.getMethod();
//
//        if (method != null) {
//            return method.getAnnotation(SysLog.class);
//        }
//        return null;
//    }


    /**
     * 得到request对象
     *
     * @return HttpServletRequest
     */
    public HttpServletRequest getRequest() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return request;
    }

    /**
     * 得到session对象
     *
     * @return HttpSession
     */
    public HttpSession getSession() {
        return this.getRequest().getSession();
    }

    public User getSessionUser() {
        User sessionUser = (User) this.getSession().getAttribute("sessionUser");
        return sessionUser;
    }

}

